﻿using Abp.Application.Services.Dto;
using Abp.Authorization.Users;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.Organizations;
using Abp.UI;
using Camc.Quality.Bop;
using Camc.Quality.Common;
using Camc.Quality.IOperationHistory;
using Camc.Quality.Organizations.Dto;
using Camc.Quality.SystemManagement;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Camc.Quality.ProductionPlan
{
    public class ProductionAssignmentAppService : QualityAppServiceBase
    {
        private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
        private readonly IRepository<UserOrganizationUnit, long> _userOrganizationUnitRepository;
        private readonly IRepository<ProductionAssignment, Guid> _productionAssignmentRepository;
        private readonly IRepository<BopDesc, Guid> _bopDescRepository;
        private readonly IOperationHistoryAppService _iOperationHistoryAppService;
        public readonly CodeFormatDescAppService _codeFormatDescAppServiceRepository;
        public ProductionAssignmentAppService(
         IRepository<OrganizationUnit, long> organizationUnitRepository,
         IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
         IRepository<ProductionAssignment, Guid> productionAssignmentRepository,
         IRepository<BopDesc, Guid> bopDescRepository,
         IOperationHistoryAppService iOperationHistoryAppService,
         CodeFormatDescAppService codeFormatDescAppServiceRepository)
        {
            _organizationUnitRepository = organizationUnitRepository;
            _userOrganizationUnitRepository = userOrganizationUnitRepository;
            _productionAssignmentRepository = productionAssignmentRepository;
            _bopDescRepository = bopDescRepository;
            _iOperationHistoryAppService = iOperationHistoryAppService;
            _codeFormatDescAppServiceRepository = codeFormatDescAppServiceRepository;
        }
        /// <summary>
        /// 获取班组及用户数量
        /// </summary>
        /// <returns></returns>
        public async Task<List<OrganizationUnitDto>> GetOrganizationUnit()
        {
            List<long> organizaList = new List<long>();
            var tempOrganization = _organizationUnitRepository.GetAll().Where(d => d.DisplayName == "57车间").FirstOrDefault();
            if (tempOrganization != null)
            {
                organizaList.Add(tempOrganization.Id);
                var childrenList = _organizationUnitRepository.GetAll().Where(d => d.ParentId == tempOrganization.Id).ToList();
                if (childrenList.Count > 0)
                {
                    organizaList.AddRange(childrenList.Select(d=>d.Id));
                }
            }

            var query = from ou in _organizationUnitRepository.GetAll()
                        join ff in organizaList on ou.Id equals ff
                        join uoUser in _userOrganizationUnitRepository.GetAll() on ou.Id equals uoUser.OrganizationUnitId into uoUserGrouped
                     
                        select new
                        {
                            ou,
                            memberCount = uoUserGrouped.Count(),
                        };

            var items = await query.ToListAsync();
            return new List<OrganizationUnitDto>(
                items.Select(item =>
                {
                    var organizationUnitDto = ObjectMapper.Map<OrganizationUnitDto>(item.ou);
                    organizationUnitDto.MemberCount = item.memberCount;
                    return organizationUnitDto;
                }).ToList());
        }
        /// <summary>
        /// 根据Id获取该班组下的人员
        /// </summary>
        /// <param name="organizationId"></param>
        /// <returns></returns>
        public async Task<List<OrganizationUnitUserListDto>> GetOrganizationUnitUsersById( List<long> organizationIdList)
        {
            var query = from ouUser in _userOrganizationUnitRepository.GetAll()
                        join ou in _organizationUnitRepository.GetAll() on ouUser.OrganizationUnitId equals ou.Id
                        join user in UserManager.Users on ouUser.UserId equals user.Id
                        where organizationIdList.Contains(ouUser.OrganizationUnitId)
                        select new
                        {
                            ouUser,
                            user
                        };

            var totalCount = await query.CountAsync();
            var items = await query.ToListAsync();

            return new List<OrganizationUnitUserListDto>(
                items.Select(item =>
                {
                    var organizationUnitUserDto = ObjectMapper.Map<OrganizationUnitUserListDto>(item.user);
                    organizationUnitUserDto.Name = item.user.Surname + item.user.Name;
                    organizationUnitUserDto.AddedTime = item.ouUser.CreationTime;
                    return organizationUnitUserDto;
                }).ToList());
        }
        /// <summary>
        /// 插入或者更新生产准备计划
        /// </summary>
        /// <param name="input"></param>
        public ResultMessage InsertOrUpdateProductionAssignment(ProductionAssignmentInput input)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                if (string.IsNullOrWhiteSpace(input.DrawingNo))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "产品图号格式不正确!";
                    return resultMessage;
                    //throw new UserFriendlyException("产品图号格式不正确!");
                }
                if (string.IsNullOrWhiteSpace(input.ProductName))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "产品名称格式不正确!";
                    return resultMessage;
                    //throw new UserFriendlyException("产品名称格式不正确!");
                }
                if (string.IsNullOrWhiteSpace(input.PreparationRemark))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "准备内容格式不正确!";
                    return resultMessage;
                    //throw new UserFriendlyException("准备内容格式不正确!");
                }
                var temp = ObjectMapper.Map<ProductionAssignment>(input);
                if (temp.Id == Guid.Empty)
                {
                    var planNumber = _codeFormatDescAppServiceRepository.GetCodeFormat("生产准备计划");
                    if (planNumber == null)
                    {
                        temp.PlanNumber = _codeFormatDescAppServiceRepository.GetOrderCode("SCZBJH", "yyyyMMdd", 1, 5, 1);
                    }
                    else
                    {
                        temp.PlanNumber = planNumber;
                    }
                    //temp.PlanNumber = _codeFormatDescAppServiceRepository.GetOrderCode("PA", "yyyyMMdd", 1, 5, 1);
                    temp.AssignmentAuthor = GetCurrentUser().Surname + GetCurrentUser().Name;
                    temp.AssignmentTime = DateTime.Now.ToString();
                    temp.AssignmentTypes = AssignmentTypes.已创建;
                    var guid = _productionAssignmentRepository.InsertAndGetId(temp);
                    _iOperationHistoryAppService.InsertOperationLog(guid, 7, 14, "新增准备计划编号:" + input.JobNumber + "信息");
                }
                else
                {
                    var data = _productionAssignmentRepository.GetAll().Where(d => d.Id == input.Id.Value).AsNoTracking().FirstOrDefault();
                    temp.AssignmentAuthor = data.AssignmentAuthor;
                    temp.AssignmentTime = data.AssignmentTime;
                    temp.AssignmentTypes = data.AssignmentTypes;
                    temp.PlanNumber = data.PlanNumber;
                    _productionAssignmentRepository.Update(temp);
                    _iOperationHistoryAppService.InsertOperationLog(input.Id.Value, 7, 15, "修改" + input.JobNumber + "信息");
                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
        /// <summary>
        /// 查询生产准备计划
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<ProductionAssignmentInput> GetAssignments(AssignmentSelectInput input)
        {
            var query = _productionAssignmentRepository.GetAll().WhereIf(input.Id!=null, item => item.Id==input.Id)
                .WhereIf(input.ModelId!=null, item => item.ModelId.ToString().ToUpper().Equals(input.ModelId.ToString().ToUpper()))
                .WhereIf(input.LotNoId != null, item => item.LotNoId.ToString().ToUpper().Equals(input.LotNoId.ToString().ToUpper()) )
                .WhereIf(!input.JobNumber.IsNullOrWhiteSpace(), item => item.JobNumber.Contains(input.JobNumber));
            int count = query.Count();
            if (query.Count() > 0)
            {
                query = query.OrderByDescending(d => d.CreationTime).PageBy(input);
            }
            return new PagedResultDto<ProductionAssignmentInput>(count, ObjectMapper.Map<List<ProductionAssignmentInput>>(query));
        }
        /// <summary>
        ///生产准备计划操作
        /// </summary>
        /// <param name="input"></param>
        public ResultMessage OptionAssignment(AssignmentOptionInput input)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                switch (input.option)
                {
                    case 0:
                        foreach (var item in input.AssignmentsId)
                        {
                            var temp = _productionAssignmentRepository.Get(item);
                            if (temp.AssignmentTypes == AssignmentTypes.已创建)
                            {
                                _productionAssignmentRepository.Delete(item);
                                _iOperationHistoryAppService.InsertOperationLog(item, 7, 24, "删除" + temp.JobNumber + "信息");
                            }
                            else
                            {
                                resultMessage.code = 1;
                                resultMessage.Message = "删除操作仅对已创建状态的数据有效!请核实后在进行操作！";
                                return resultMessage;
                                //throw new UserFriendlyException("删除操作仅对已创建状态的数据有效!请核实后在进行操作！");
                            }
                        }
                        break;
                    case 1:
                        foreach (var item in input.AssignmentsId)
                        {
                            var temp = _productionAssignmentRepository.Get(item);
                            temp.AssignmentTypes = AssignmentTypes.已启动;
                            temp.StartTime = DateTime.Now.ToString();
                            _productionAssignmentRepository.Update(temp);
                            _iOperationHistoryAppService.InsertOperationLog(item, 7, 22, "启动" + temp.JobNumber);
                        }
                        break;
                    case 2:
                        foreach (var item in input.AssignmentsId)
                        {
                            var temp = _productionAssignmentRepository.Get(item);
                            temp.AssignmentTypes = AssignmentTypes.已完成;
                            temp.EndTime = DateTime.Now.ToString();
                            _productionAssignmentRepository.Update(temp);
                            _iOperationHistoryAppService.InsertOperationLog(item, 7, 23, "完成" + temp.JobNumber);
                        }; break;
                    default:
                        resultMessage.code = 1;
                        resultMessage.Message = "当前操作无效!请核实后在进行操作！";
                        return resultMessage;
                        //throw new UserFriendlyException("当前操作无效!请核实后在进行操作！"); 
                        break;
                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }

        /// <summary>
        /// 生产计划型号的模糊查询
        /// </summary>
        /// <param name="model">为空则全库查</param>
        /// <returns></returns>
        public List<string> GetAssignmentModelList(string model)
        {
            var query = _bopDescRepository.GetAll();
            if (string.IsNullOrEmpty(model))
            {
                return query.Select(d => d.Model).Distinct().ToList();
            }
            else
            {
                return query.Where(d => d.Model.Contains(model)).Select(d => d.Model).Distinct().ToList();
            }
        }

        /// <summary>
        /// 生产计划发次的模糊查询（基于型号查询数据）必须先选择型号
        /// </summary>
        /// <param name="lotstr"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public List<string> GetLotNoList(string lotstr, string model)
        {
            var query = _bopDescRepository.GetAll();
            if (!string.IsNullOrEmpty(model))
            {
                query = query.Where(d => d.Model.Contains(model));
                if (!string.IsNullOrEmpty(lotstr))
                {
                    query = query.Where(d => d.LotNo.Contains(lotstr));
                }
                return query.Select(d => d.LotNo).Distinct().ToList();
            }
            else
            {

                throw new UserFriendlyException("请先选择型号！");
            }
        }
        /// <summary>
        /// 引用生产准备计划
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ResultMessage IntroducePlan(IntroducePlanInput input)
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                if (!string.IsNullOrEmpty(input.JobNumber))
                {
                    var tempArray = input.JobNumber.Split('/');
                    if (tempArray.Length == 2)
                    {
                        var lotNo = tempArray[1];
                        var model = tempArray[0];
                        var proTemp = _productionAssignmentRepository.GetAll().Where(d => d.LotNo == lotNo && d.Model == model);
                        foreach (var item in proTemp)
                        {
                            item.Id = Guid.NewGuid();
                            item.CreationTime = DateTime.Now;
                            item.LotNo = input.LotNo;
                            item.Model = input.Model;
                            item.ModelId = input.ModelId;
                            item.LotNoId = input.LotNoId;
                            item.DrawingNo = input.DrawingNo;
                            item.ProductName = input.ProductName;
                            var planNumber = _codeFormatDescAppServiceRepository.GetCodeFormat("生产准备计划");
                            if (planNumber == null)
                            {
                                item.PlanNumber = _codeFormatDescAppServiceRepository.GetOrderCode("SCZBJH", "yyyyMMdd", 1, 5, 1);
                            }
                            else
                            {
                                item.PlanNumber = planNumber;
                            }
                            //item.PlanNumber= _codeFormatDescAppServiceRepository.GetOrderCode("PA", "yyyyMMdd", 1, 5, 1);
                            if (!string.IsNullOrEmpty(item.LotNo) && !string.IsNullOrEmpty(item.Model))
                            {
                                item.JobNumber = item.Model + "/" + item.LotNo;
                            }
                            _productionAssignmentRepository.Insert(item);
                        }
                        resultMessage.code = 0;
                        return resultMessage;
                    }
                    else
                    {
                        resultMessage.code = 1;
                        resultMessage.Message = "引用生产准备计划失败!";
                        return resultMessage;
                    }
                }
                else
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "任务编号不可为空!";
                    return resultMessage;
                    //throw new UserFriendlyException("任务编号不可为空!");
                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
    }

}

